<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>大数据之开源缓存数据库 Redis | Oct25-X</title><meta name="keywords" content="Redis"><meta name="author" content="Oct25-X"><meta name="copyright" content="Oct25-X"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="数据库简介一、NoSQL 概述 NoSQL（NoSQL &#x3D; Not Only SQL ），意即“不仅仅是 SQL”，泛指非关系型的数据库。 NoSQL 不依赖业务逻辑方式存储，而以简单的 key-value 模式存储。因此大大的增加了数据库的扩展能力。 不遵循 SQL 标准。 不支持 ACID。 远超于 SQL 的性能。  二、NoSQL 的适用场景 对数据高并发的读写。 海量数据的读写">
<meta property="og:type" content="article">
<meta property="og:title" content="大数据之开源缓存数据库 Redis">
<meta property="og:url" content="https://oct25-x.atomgit.net/oct25-xxxxx/2023/07/04/10%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%BC%80%E6%BA%90%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93%20Redis/index.html">
<meta property="og:site_name" content="Oct25-X">
<meta property="og:description" content="数据库简介一、NoSQL 概述 NoSQL（NoSQL &#x3D; Not Only SQL ），意即“不仅仅是 SQL”，泛指非关系型的数据库。 NoSQL 不依赖业务逻辑方式存储，而以简单的 key-value 模式存储。因此大大的增加了数据库的扩展能力。 不遵循 SQL 标准。 不支持 ACID。 远超于 SQL 的性能。  二、NoSQL 的适用场景 对数据高并发的读写。 海量数据的读写">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://oct25-x.atomgit.net/oct25-xxxxx/img/cover_img/ctt10.png">
<meta property="article:published_time" content="2023-07-04T12:19:36.000Z">
<meta property="article:modified_time" content="2024-02-17T14:15:43.868Z">
<meta property="article:author" content="Oct25-X">
<meta property="article:tag" content="Redis">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://oct25-x.atomgit.net/oct25-xxxxx/img/cover_img/ctt10.png"><link rel="shortcut icon" href="/oct25-xxxxx/img/logo.jpg"><link rel="canonical" href="https://oct25-x.atomgit.net/oct25-xxxxx/2023/07/04/10%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%BC%80%E6%BA%90%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93%20Redis/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/oct25-xxxxx/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/oct25-xxxxx/',
  algolia: undefined,
  localSearch: {"path":"search.json","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '大数据之开源缓存数据库 Redis',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-02-17 22:15:43'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/rightMenu.css"><meta name="generator" content="Hexo 6.1.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/oct25-xxxxx/img/avatar.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data is-center"><div class="data-item"><a href="/oct25-xxxxx/archives/"><div class="headline">文章</div><div class="length-num">52</div></a></div><div class="data-item"><a href="/oct25-xxxxx/tags/"><div class="headline">标签</div><div class="length-num">17</div></a></div><div class="data-item"><a href="/oct25-xxxxx/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('/oct25-xxxxx/img/top_img/top_bg9.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/oct25-xxxxx/">Oct25-X</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/oct25-xxxxx/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">大数据之开源缓存数据库 Redis</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-07-04T12:19:36.000Z" title="发表于 2023-07-04 20:19:36">2023-07-04</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-02-17T14:15:43.868Z" title="更新于 2024-02-17 22:15:43">2024-02-17</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/oct25-xxxxx/categories/NoSQL%E6%95%B0%E6%8D%AE%E5%BA%93/">NoSQL数据库</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="大数据之开源缓存数据库 Redis"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="数据库简介"><a href="#数据库简介" class="headerlink" title="数据库简介"></a>数据库简介</h1><h2 id="一、NoSQL-概述"><a href="#一、NoSQL-概述" class="headerlink" title="一、NoSQL 概述"></a>一、NoSQL 概述</h2><ol>
<li>NoSQL（NoSQL &#x3D; Not Only SQL ），意即“不仅仅是 SQL”，泛指非关系型的数据库。</li>
<li>NoSQL 不依赖业务逻辑方式存储，而以简单的 <strong>key-value</strong> 模式存储。因此大大的增加了数据库的扩展能力。</li>
<li>不遵循 SQL 标准。</li>
<li>不支持 ACID。</li>
<li>远超于 SQL 的性能。</li>
</ol>
<h2 id="二、NoSQL-的适用场景"><a href="#二、NoSQL-的适用场景" class="headerlink" title="二、NoSQL 的适用场景"></a>二、NoSQL 的适用场景</h2><ol>
<li>对数据高并发的读写。</li>
<li>海量数据的读写。</li>
<li>对数据高可扩展性的。</li>
</ol>
<h2 id="三、NoSQL-不适用场景"><a href="#三、NoSQL-不适用场景" class="headerlink" title="三、NoSQL 不适用场景"></a>三、NoSQL 不适用场景</h2><ol>
<li>需要事务支持。</li>
<li>基于 sql 的结构化查询存储，处理复杂的关系,需要即席查询。</li>
</ol>
<h2 id="四、NoSQL-数据库"><a href="#四、NoSQL-数据库" class="headerlink" title="四、NoSQL 数据库"></a>四、NoSQL 数据库</h2><h3 id="缓存数据库"><a href="#缓存数据库" class="headerlink" title="缓存数据库"></a>缓存数据库</h3><p><strong>Memcached</strong></p>
<p><img src="/oct25-xxxxx/img/redis/01_Memcached.png" alt="Memcached"></p>
<ol>
<li>很早出现的NoSql数据库；</li>
<li>数据都在内存中，一般不持久化；</li>
<li>支持简单的 key-value 模式；</li>
<li>一般是作为缓存数据库辅助持久化的数据库；</li>
<li>多线程 + 锁的机制。</li>
</ol>
<p><strong>Redis</strong></p>
<p><img src="/oct25-xxxxx/img/redis/02_Redis.png" alt="Redis"></p>
<ol>
<li>几乎覆盖了 Memcached 的绝大部分功能；</li>
<li>数据都在内存中，支持持久化，主要用作备份恢复；</li>
<li>除了支持简单的 key-value 模式，还支持多种数据结构的存储，比如 list、set、hash、zset等；</li>
<li>一般是作为缓存数据库辅助持久化的数据库；</li>
<li>单线程 + 多路 IO 复用技术。</li>
</ol>
<h3 id="文档数据库"><a href="#文档数据库" class="headerlink" title="文档数据库"></a>文档数据库</h3><p><strong>MongoDB</strong></p>
<p><img src="/oct25-xxxxx/img/redis/03_MongoDB.png" alt="MongoDB"></p>
<ol>
<li>高性能、开源、模式自由(schema free)的文档型数据库；</li>
<li>数据都在内存中， 如果内存不足，把不常用的数据保存到硬盘；</li>
<li>虽然是 key-value 模式，但是对 value（尤其是 json）提供了丰富的查询功能；</li>
<li>支持二进制数据及大型对象；</li>
<li>可以根据数据的特点替代 RDBMS ，成为独立的数据库。或者配合 RDBMS，存储特定的数据。</li>
</ol>
<h3 id="列式数据库"><a href="#列式数据库" class="headerlink" title="列式数据库"></a>列式数据库</h3><p><strong>HBASE</strong></p>
<p><img src="/oct25-xxxxx/img/redis/04_HBase.png" alt="HBASE"></p>
<p>HBase 是 <strong>Hadoop</strong> 项目中的数据库。它用于需要对<strong>大量的数据进行随机、实时的读写操作</strong>的场景中。HBase 的目标就是处理数据量非常庞大的表，可以用普通的计算机处理超过10亿行数据，还可处理有数百万列元素的数据表。</p>
<p><strong>CASSANDRA</strong></p>
<p><img src="/oct25-xxxxx/img/redis/05_CASSANDRA.png" alt="CASSANDRA"></p>
<p>Apache Cassandra 是一款免费的开源 NoSQL 数据库，其设计目的在于管理由大量商用服务器构建起来的庞大集群上的**海量数据集(数据量通常达到 PB 级别)**。在众多显著特性当中，Cassandra 最为卓越的长处是对写入及读取操作进行规模调整，而且其不强调主集群的设计思路能够以相对直观的方式简化各集群的创建与扩展流程。</p>
<h3 id="图关系数据库"><a href="#图关系数据库" class="headerlink" title="图关系数据库"></a>图关系数据库</h3><p><strong>ZNeo4j</strong></p>
<p><img src="/oct25-xxxxx/img/redis/06_Neo4j.png" alt="ZNeo4j"></p>
<p>主要应用：社会关系，公共交通网络，地图及网络拓谱</p>
<h1 id="Redis-介绍及安装启动"><a href="#Redis-介绍及安装启动" class="headerlink" title="Redis 介绍及安装启动"></a>Redis 介绍及安装启动</h1><h2 id="一、Redis介绍"><a href="#一、Redis介绍" class="headerlink" title="一、Redis介绍"></a>一、Redis介绍</h2><p>Redis 是一个开源的 key-value 存储系统。和 Memcached 类似，它支持存储的 value 类型相对更多，包括 string（字符串）、list（链表）、set（集合）、zset（sorted set 有序集合）和 hash（哈希类型）。这些数据类型都支持 push&#x2F;pop、add&#x2F;remove 及取交集并集和差集及更丰富的操作，而且这些操作都是原子性的。在此基础上，Redis支持各种不同方式的排序。 </p>
<p>为了保证效率，数据都是<strong>缓存在内存</strong>中。区别的是 Redis 会周期性的把更新的数据写入磁盘或者修改操作写入追加的记录文件，并且在此基础上实现了 master-slave（主从）同步。</p>
<h2 id="二、Redis-应用场景"><a href="#二、Redis-应用场景" class="headerlink" title="二、Redis 应用场景"></a>二、Redis 应用场景</h2><ol>
<li>配合关系型数据库做高速缓存；<ul>
<li>高频次，热门访问的数据，降低数据库IO；</li>
<li>分布式架构，做session共享；</li>
</ul>
</li>
<li>由于其拥有持久化能力，利用其多样的数据结构存储特定的数据；</li>
</ol>
<h2 id="三、Redis-安装"><a href="#三、Redis-安装" class="headerlink" title="三、Redis 安装"></a>三、Redis 安装</h2><p>默认16个数据库，类似数组下标从0开始，初始默认使用0号库；</p>
<ul>
<li>使用命令 select &lt;dbid&gt; 来切换数据库。如：select 8</li>
</ul>
<p>统一密码管理，所有库都是同样密码，要么都 OK 要么一个也连接不上。</p>
<h3 id="安装部署-Redis"><a href="#安装部署-Redis" class="headerlink" title="安装部署 Redis"></a>安装部署 Redis</h3><ol>
<li>将下载好的 redis-7.0.8.tar.gz 放入 Linux 的 &#x2F;opt&#x2F;software&#x2F; 目录下；</li>
<li>解压命令：</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -zxvf redis-7.0.8.tar.gz -C /opt/module/</span><br></pre></td></tr></table></figure>

<ol start="3">
<li>在解压目录 redis-7.0.8 下执行 make 命令</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">在执行 make 命令时，会出现故障：gcc：命令未找到</span><br><span class="line"></span><br><span class="line">这时，在有网的环境下执行以下命令操作：</span><br><span class="line">yum install gcc</span><br><span class="line">yum install gcc-c++</span><br></pre></td></tr></table></figure>

<p><strong>Tips</strong>：</p>
<p>yum 命令报错提示：<strong>Cannot find a valid baseurl for repo: base&#x2F;7&#x2F;x86_64</strong></p>
<p>解决办法：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /etc/resolv.conf</span><br></pre></td></tr></table></figure>

<p>添加发下两行代码：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nameserver 114.114.114.114</span><br><span class="line">nameserver 8.8.8.8</span><br></pre></td></tr></table></figure>

<p>重启网上：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl restart network</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>完成后，再次进入 Redis-7.0.8 目录下，执行 make 命令</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">提示：Jemalloc/jemalloc.h：没有那个文件</span><br><span class="line"></span><br><span class="line">解决方案：先运行 make distclean 之后再运行 make 命令</span><br></pre></td></tr></table></figure>

<ol start="5">
<li>执行 make 命令</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">make distclean</span><br><span class="line">make</span><br><span class="line">make install</span><br></pre></td></tr></table></figure>

<ol start="6">
<li>完成后，查看默认安装目录：&#x2F;usr&#x2F;local&#x2F;bin</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">ll /usr/local/bin</span><br><span class="line"></span><br><span class="line">redis-benchmark：性能测试工具，可以在自己本子运行，看看自己本子性能如何(服务启动起来后执行)</span><br><span class="line">redis-check-aof：修复有问题的AOF文件，rdb和aof后面讲</span><br><span class="line">redis-check-rdb：修复有问题的dump.rdb文件</span><br><span class="line">redis-sentinel：Redis集群使用</span><br><span class="line">redis-server：Redis服务器启动命令</span><br><span class="line">redis-cli：客户端，操作入口</span><br></pre></td></tr></table></figure>

<ol start="7">
<li>启动 Redis</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-server</span><br></pre></td></tr></table></figure>

<h3 id="配置-Redis-后台启动"><a href="#配置-Redis-后台启动" class="headerlink" title="配置 Redis 后台启动"></a>配置 Redis 后台启动</h3><ol>
<li>备份 &#x2F;opt&#x2F;model&#x2F;redis-3.2.5&#x2F;redis.conf：拷贝一份 redis.conf 到其他目录</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /opt/module</span><br><span class="line"></span><br><span class="line"><span class="built_in">cp</span> ./redis-3.2.5/redis.conf ./</span><br><span class="line"></span><br><span class="line">ll</span><br><span class="line"></span><br><span class="line">总用量 52</span><br><span class="line">drwxrwxr-x. 6 xkee xkee  4096 2月  11 22:00 redis-3.2.5</span><br><span class="line">-rw-r--r--. 1 root root 46695 2月  11 22:01 redis.conf</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>修改 redis.conf 文件将里面的 daemonize no 改成 yes（128行），让服务在后台启动</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">vim redis.conf</span><br><span class="line"></span><br><span class="line">daemonize <span class="built_in">yes</span></span><br></pre></td></tr></table></figure>

<ol start="3">
<li>启动 Redis</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-server ./redis.conf</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>查看 Redis 是否后台运行</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">ps -ef | grep redis</span><br><span class="line"></span><br><span class="line">xkee   9113     1  0 20:11 ?        00:00:00 redis-server 127.0.0.1:6379</span><br><span class="line">xkee   9117  2201  0 20:11 pts/0    00:00:00 grep redis</span><br></pre></td></tr></table></figure>

<ol start="5">
<li>用客户端访问</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-cli</span><br></pre></td></tr></table></figure>

<ol start="6">
<li>测试客户端是否连接成功</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1:6379&gt; ping</span><br><span class="line">PONG</span><br></pre></td></tr></table></figure>

<ul>
<li>返回 PONG 即连接成功</li>
</ul>
<h3 id="配置-Redis-远程连接"><a href="#配置-Redis-远程连接" class="headerlink" title="配置 Redis 远程连接"></a>配置 Redis 远程连接</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#修改远程连接</span></span><br><span class="line"><span class="built_in">bind</span> 0.0.0.0</span><br><span class="line"></span><br><span class="line"><span class="comment">#关闭保护模式</span></span><br><span class="line">protected-mode no</span><br></pre></td></tr></table></figure>

<h3 id="Redis-关闭"><a href="#Redis-关闭" class="headerlink" title="Redis 关闭"></a>Redis 关闭</h3><ol>
<li>单实例关闭</li>
</ol>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">redis-cli shutdown</span><br><span class="line"></span><br><span class="line">或者在 Redis 终端中使用如下命令</span><br><span class="line">192.168.8.101:6379&gt; shutdown</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>多实例关闭，指定端口号进行关闭</li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-cli -p 6379 shutdown</span><br></pre></td></tr></table></figure>

<h2 id="四、Redis-的单线程-多路-IO-复用技术"><a href="#四、Redis-的单线程-多路-IO-复用技术" class="headerlink" title="四、Redis 的单线程 + 多路 IO 复用技术"></a>四、Redis 的单线程 + 多路 IO 复用技术</h2><p>多路复用是指使用一个线程来检查多个文件描述符（Socket）的就绪状态，比如调用 select 和 poll 函数，传入多个文件描述符，如果有一个文件描述符就绪，则返回，否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行，也可以启动线程执行（比如使用线程池）。</p>
<h1 id="Redis-五大数据类型"><a href="#Redis-五大数据类型" class="headerlink" title="Redis 五大数据类型"></a>Redis 五大数据类型</h1><h2 id="一、Key"><a href="#一、Key" class="headerlink" title="一、Key"></a>一、Key</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">keys *					  查询当前库的所有键</span><br><span class="line">exists &lt;key&gt;			判断某个键是否存在</span><br><span class="line">type &lt;key&gt;  			查看键对应的数据的类型</span><br><span class="line">del &lt;key&gt;				  删除某个键</span><br><span class="line"></span><br><span class="line">expire &lt;key&gt; &lt;seconds&gt;	为键值设置过期时间，单位秒</span><br><span class="line">ttl   &lt;key&gt; 			查看还有多少秒过期，-1表示永不过期，-2表示已过期</span><br><span class="line"></span><br><span class="line">dbsize  				  查看当前数据库的key的数量</span><br><span class="line">flushdb					  清空当前库</span><br><span class="line">flushall				  通杀全部库</span><br></pre></td></tr></table></figure>

<h2 id="二、String"><a href="#二、String" class="headerlink" title="二、String"></a>二、String</h2><ul>
<li>tring 是 Redis 最基本的类型，你可以理解成与 Memcached 一模一样的类型，一个 key 对应一个 value。</li>
<li>String 类型是二进制安全的。意味着 Redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象 。</li>
<li>String 类型是 Redis 最基本的数据类型，一个 Redis 中字符串 value 最多可以是512M。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">get &lt;key&gt;					查询对应键值</span><br><span class="line">set &lt;key&gt; &lt;value&gt;			添加键值对</span><br><span class="line">append &lt;key&gt; &lt;value&gt;		将给定的&lt;value&gt; 追加到原值的末尾</span><br><span class="line">strlen &lt;key&gt;				获得值的长度</span><br><span class="line">setnx &lt;key&gt; &lt;value&gt;			只有在 key 不存在时设置 key 的值</span><br><span class="line"></span><br><span class="line">incr &lt;key&gt;					将 key 中储存的数字值增<span class="number">1</span>；只能对数字值操作，如果为空，新增值为<span class="number">1</span></span><br><span class="line">decr &lt;key&gt;					将 key 中储存的数字值减<span class="number">1</span>；只能对数字值操作，如果为空，新增值为-<span class="number">1</span></span><br><span class="line">incrby/decrby &lt;key&gt; &lt;步长&gt;	将 key 中储存的数字值增减。自定义步长。</span><br><span class="line"></span><br><span class="line">mset &lt;key1&gt; &lt;value1&gt; &lt;key2&gt; &lt;value2&gt;  ..... 	同时设置一个或多个 key-value对  </span><br><span class="line">mget &lt;key1&gt; &lt;key2&gt; &lt;key3&gt; .....					同时获取一个或多个 value  </span><br><span class="line">msetnx &lt;key1&gt; &lt;value1&gt; &lt;key2&gt; &lt;value2&gt;  ..... 	同时设置一个或多个 key-value 对，当且仅当所有给定 key 都不存在。</span><br><span class="line"></span><br><span class="line">getrange &lt;key&gt; &lt;起始位置&gt; &lt;结束位置&gt;	获得值的范围，类似java中的substring</span><br><span class="line">setrange &lt;key&gt; &lt;起始位置&gt; &lt;value&gt;		用 &lt;value&gt;  覆写&lt;key&gt; 所储存的字符串值，从&lt;起始位置&gt;开始。</span><br><span class="line"></span><br><span class="line">setex &lt;key&gt; &lt;过期时间&gt; &lt;value&gt;		设置键值的同时，设置过期时间，单位秒。</span><br><span class="line">getset &lt;key&gt; &lt;value&gt;				以新换旧，设置了新值同时获得旧值。</span><br></pre></td></tr></table></figure>

<h3 id="原子性"><a href="#原子性" class="headerlink" title="原子性"></a>原子性</h3><blockquote>
<p>所谓原子操作是指不会被线程调度机制打断的操作；这种操作一旦开始，就一直运行到结束，中间不会有任何 context switch （切换到另一个线程）。</p>
</blockquote>
<p>（1） 在单线程中， 能够在单条指令中完成的操作都可以认为是” 原子操作”，因为中断只能发生于指令之间。</p>
<p>（2）在多线程中，不能被其它进程（线程）打断的操作就叫原子操作。</p>
<p><strong>Redis 单命令的原子性主要得益于 Redis 的单线程</strong></p>
<h2 id="三、List"><a href="#三、List" class="headerlink" title="三、List"></a>三、List</h2><p>单键多值 Redis 列表是简单的字符串列表，按照插入顺序排序。你可以添加一个元素到列表的头部（左边）或者尾部（右边）。 它的底层实际是个双向链表，对两端的操作性能很高，通过索引下标的操作中间的节点性能会较差。</p>
<p><img src="/oct25-xxxxx/img/redis/07_List.png" alt="List"></p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">lpush/rpush &lt;key&gt; &lt;value1&gt; &lt;value2&gt; &lt;value3&gt; ....	从左边/右边插入一个或多个值。</span><br><span class="line">lpop/rpop &lt;key&gt; 			从左边/右边吐出一个值；值在键在，值亡键亡。</span><br><span class="line">rpoplpush &lt;key1&gt; &lt;key2&gt; 	从&lt;key1&gt;列表右边吐出一个值，插到&lt;key2&gt;列表左边。</span><br><span class="line"> </span><br><span class="line">lrange &lt;key&gt; &lt;start&gt; &lt;stop&gt;	按照索引下标获得元素(从左到右)</span><br><span class="line">lindex &lt;key&gt; &lt;index&gt;		按照索引下标获得元素(从左到右)</span><br><span class="line">llen &lt;key&gt;		获得列表长度 </span><br><span class="line"></span><br><span class="line">linsert &lt;key&gt; before &lt;value&gt; &lt;newvalue&gt;   	在&lt;value&gt;的前面插入&lt;newvalue&gt; </span><br><span class="line">lrem &lt;key&gt; &lt;n&gt; &lt;value&gt;						从左边删除n个value(从左到右)，n&gt;实际个数，忽略不计，以实际为准</span><br></pre></td></tr></table></figure>

<h2 id="四、Set"><a href="#四、Set" class="headerlink" title="四、Set"></a>四、Set</h2><p>Redis set对外提供的功能与 list 类似是一个列表的功能，特殊之处在于 set 是可以自动排重的，当你需要存储一个列表数据，又不希望出现重复数据时，set 是一个很好的选择，并且 set 提供了判断某个成员是否在一个set集合内的重要接口，这个也是 list 所不能提供的。 Redis 的 Set 是 string 类型的无序集合。它底层其实是一个 value 为 null 的 hash 表，所以添加，删除，查找的复杂度都是O(1)。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">sadd &lt;key&gt; &lt;value1&gt; &lt;value2&gt; .....   将一个或多个 member 元素加入到集合 key 当中，已经存在于集合的 member 元素将被忽略。</span><br><span class="line">smembers &lt;key&gt;						取出该集合的所有值。</span><br><span class="line">sismember &lt;key&gt; &lt;value&gt;				判断集合&lt;key&gt;是否为含有该&lt;value&gt;值，有返回1，没有返回0</span><br><span class="line"></span><br><span class="line">scard &lt;key&gt;							返回该集合的元素个数。</span><br><span class="line">srem &lt;key&gt; &lt;value1&gt; &lt;value2&gt; .... 	删除集合中的某个元素。</span><br><span class="line">spop &lt;key&gt; &lt;n&gt;   					随机从该集合中吐出一个或多个值。会从集合删除</span><br><span class="line">srandmember &lt;key&gt; &lt;n&gt;				随机从该集合中取出n个值；不会从集合中删除</span><br><span class="line"></span><br><span class="line">sinter &lt;key1&gt; &lt;key2&gt;				返回两个集合的交集元素。</span><br><span class="line">sunion &lt;key1&gt; &lt;key2&gt;				返回两个集合的并集元素。</span><br><span class="line">sdiff &lt;key1&gt; &lt;key2&gt;  	 			返回两个集合的差集元素。</span><br></pre></td></tr></table></figure>

<h2 id="五、Hash"><a href="#五、Hash" class="headerlink" title="五、Hash"></a>五、Hash</h2><blockquote>
<p>Redis hash 是一个键值对集合。 Redis hash是一个 string 类型的 field 和 value 的映射表，hash 特别适合用于存储对象。 类似 Java 里面的 Map&lt;String,Object&gt;</p>
</blockquote>
<h3 id="Hash-数据的存储"><a href="#Hash-数据的存储" class="headerlink" title="Hash 数据的存储"></a>Hash 数据的存储</h3><p>key 为用户 ID，value 为用户对象，并包含姓名、年龄、生日等信息，如果用普通的key&#x2F;value结构来存储，主要有以下2种存储方式：</p>
<p><img src="/oct25-xxxxx/img/redis/08_Hash1.png"></p>
<p>Hash 数据结构中数据的存储：</p>
<p><img src="/oct25-xxxxx/img/redis/09_Hash2.png"></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">hset &lt;key&gt; &lt;field&gt; &lt;value&gt;		给&lt;key&gt;集合中的  &lt;field&gt;键赋值&lt;value&gt;</span><br><span class="line">hget &lt;key&gt; &lt;field&gt;    			从&lt;key&gt;集合&lt;field&gt; 取出 value </span><br><span class="line">hmset &lt;key&gt; &lt;field1&gt; &lt;value1&gt; &lt;field2&gt; &lt;value2&gt;...    批量设置hash的值</span><br><span class="line"></span><br><span class="line">hexists key &lt;field&gt;			查看哈希表 key 中，给定域 field 是否存在</span><br><span class="line">hkeys &lt;key&gt;    				列出该hash集合的所有field</span><br><span class="line">hvals &lt;key&gt;     			列出该hash集合的所有value</span><br><span class="line">hincrby &lt;key&gt; &lt;field&gt; &lt;increment&gt; 		为哈希表 key 中的域 field 的值加上增量 increment </span><br><span class="line">hsetnx &lt;key&gt; &lt;field&gt; &lt;value&gt;			将哈希表 key 中的域 field 的值设置为 value ，当且仅当域 field 不存在</span><br></pre></td></tr></table></figure>

<h2 id="六、Zset"><a href="#六、Zset" class="headerlink" title="六、Zset"></a>六、Zset</h2><p>Redis 有序集合 zset 与普通集合 set 非常相似，是一个没有重复元素的字符串集合。不同之处是有序集合的所有成员都关联了一个评分（score） ，这个评分（score）被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的，但是评分可以是重复的 。 因为元素是有序的, 所以你也可以很快的根据评分（score）或者次序（position）来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">zadd &lt;key&gt; &lt;score1&gt; &lt;value1&gt; &lt;score2&gt; &lt;value2&gt;...		</span><br><span class="line">					将一个或多个 member 元素及其 score 值加入到有序集 key 当中。</span><br><span class="line">zrange &lt;key&gt; &lt;start&gt; &lt;stop&gt; [WITHSCORES]   		</span><br><span class="line">					返回有序集 key 中，下标在&lt;start&gt; &lt;stop&gt;之间的元素；带WITHSCORES，可以让分数一起和值返回到结果集。</span><br><span class="line">zrangebyscore key min max [withscores] [limit offset count]		</span><br><span class="line">					返回有序集 key 中，所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 </span><br><span class="line">zrevrangebyscore key max min [withscores] [limit offset count]	 同上，改为从大到小排列。 </span><br><span class="line"></span><br><span class="line">zincrby &lt;key&gt; &lt;increment&gt; &lt;value&gt;		为元素的score加上增量</span><br><span class="line">zrem &lt;key&gt; &lt;value&gt;  					删除该集合下，指定值的元素 </span><br><span class="line">zcount &lt;key&gt; &lt;min&gt; &lt;max&gt; 				统计该集合，分数区间内的元素个数 </span><br><span class="line">zrank &lt;key&gt; &lt;value&gt; 					返回该值在集合中的排名，从<span class="number">0</span>开始。</span><br></pre></td></tr></table></figure>

<h1 id="Redis-的-Java-客户端-Jedis"><a href="#Redis-的-Java-客户端-Jedis" class="headerlink" title="Redis 的 Java 客户端 Jedis"></a>Redis 的 Java 客户端 Jedis</h1><h2 id="一、Jedis-简介"><a href="#一、Jedis-简介" class="headerlink" title="一、Jedis 简介"></a>一、Jedis 简介</h2><p>简单来说，Jedis 就是 Redis 官方推荐的 Java 连接开发工具；</p>
<p>在 Java 中，Redis 对应于 Jedis 就相当于关系数据库的 JDBC。</p>
<h2 id="二、Jedis-的使用"><a href="#二、Jedis-的使用" class="headerlink" title="二、Jedis 的使用"></a>二、Jedis 的使用</h2><ol>
<li>创建 Maven 项目</li>
</ol>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.example.redis<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>RedisClientDemo<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>1.0-SNAPSHOT<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ol start="2">
<li>导入依赖</li>
</ol>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>redis.clients<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jedis<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>4.4.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>

<ol start="3">
<li>使用 Jedis 连接 Redis 简单示例</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.example.jedis;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span> TODO Redis客户端 Jedis示例</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JedisTest</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">//创建Jedis对象</span></span><br><span class="line">        <span class="type">Jedis</span> <span class="variable">jedis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Jedis</span>(<span class="string">&quot;hadoop105&quot;</span>, <span class="number">6379</span>);</span><br><span class="line">        <span class="comment">//测试是否连接成功</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">isConn</span> <span class="operator">=</span> jedis.ping();</span><br><span class="line">        System.out.println(isConn);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="三、Jedis-连接池"><a href="#三、Jedis-连接池" class="headerlink" title="三、Jedis 连接池"></a>三、Jedis 连接池</h2><p>Jedis 提供了连接池机制，所以在生产环境中需要向 Jedis 连接池获取对 Redis 的连接。Jedis 的连接池类为 redis.clients.jedis.JedisPool。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 初始化连接池类（使用默认连接池参数）</span></span><br><span class="line"><span class="type">JedisPool</span> <span class="variable">jp</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JedisPool</span>(<span class="string">&quot;192.168.8.101&quot;</span>, <span class="number">6379</span>);</span><br><span class="line"><span class="comment">// 获取一个Jedis连接</span></span><br><span class="line"><span class="type">Jedis</span> <span class="variable">jedis</span> <span class="operator">=</span> jp.getResource();</span><br></pre></td></tr></table></figure>

<p>上面这个示例，只为连接池指定了要连接的 Redis 的IP和端口号，而未指定连接池的其他参数。</p>
<p>查看源码，可以知道JedisPool的这个构造方法使用了 <strong>GenericObjectPoolConfig</strong> 这个类对象来设定Jedis连接池的默认参数：</p>
<p><img src="/oct25-xxxxx/img/redis/10_Jedis1.png"></p>
<p><img src="/oct25-xxxxx/img/redis/11_Jedis2.png"></p>
<h3 id="自定义-Jedis-连接池的参数"><a href="#自定义-Jedis-连接池的参数" class="headerlink" title="自定义 Jedis 连接池的参数"></a>自定义 Jedis 连接池的参数</h3><p><strong>JedisPoolConfig</strong> 类是 <strong>GenericObjectPoolConfig</strong> 类的子类，因此可以使用它来自定义Jedis连接池的参数：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JedisPoolConfig</span> <span class="variable">config</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JedisPoolConfig</span>();</span><br><span class="line">config.setMaxTotal(<span class="number">30</span>); <span class="comment">//设置连接池最大连接数</span></span><br><span class="line">config.setMaxIdle(<span class="number">8</span>); <span class="comment">//设置连接池允许最大空闲连接数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//初始化连接池</span></span><br><span class="line"><span class="type">JedisPool</span> <span class="variable">jedisPool</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JedisPool</span>(config, <span class="string">&quot;192.168.8.105&quot;</span>, <span class="number">6379</span>);</span><br><span class="line"><span class="comment">//获取连接</span></span><br><span class="line"><span class="type">Jedis</span> <span class="variable">jedis</span> <span class="operator">=</span> jedisPool.getResource();</span><br></pre></td></tr></table></figure>

<h2 id="四、Jedis-的-Java-工具类"><a href="#四、Jedis-的-Java-工具类" class="headerlink" title="四、Jedis 的 Java 工具类"></a>四、Jedis 的 Java 工具类</h2><p>封装连接参数：src&#x2F;jedisConfig.properties</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">jedis.host=<span class="number">192.168</span><span class="number">.8</span><span class="number">.101</span></span><br><span class="line">jedis.port=<span class="number">6379</span></span><br><span class="line">jedis.maxTotal=<span class="number">30</span></span><br><span class="line">jedis.maxIdle=<span class="number">10</span></span><br></pre></td></tr></table></figure>

<p>工具类代码：JedisUtils.java</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.example.jedis;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPoolConfig;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.util.Properties;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span> TODO</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JedisUtils</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> JedisPool jedisPool;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="comment">//加载配置参数</span></span><br><span class="line">        <span class="type">Properties</span> <span class="variable">properties</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Properties</span>();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            properties.load(JedisUtils.class.getResourceAsStream(<span class="string">&quot;/jedisConfig.propertids&quot;</span>));</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//获取属性</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">host</span> <span class="operator">=</span> properties.getProperty(<span class="string">&quot;jedis.host&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">port</span> <span class="operator">=</span> Integer.parseInt(properties.getProperty(<span class="string">&quot;jedis.port&quot;</span>));</span><br><span class="line">        <span class="type">int</span> <span class="variable">maxTotal</span> <span class="operator">=</span> Integer.parseInt(properties.getProperty(<span class="string">&quot;jedis.maxTotal&quot;</span>));</span><br><span class="line">        <span class="type">int</span> <span class="variable">maxIdle</span> <span class="operator">=</span> Integer.parseInt(properties.getProperty(<span class="string">&quot;jedis.maxIdle&quot;</span>));</span><br><span class="line"></span><br><span class="line">        <span class="comment">//设置Jedis连接池参数</span></span><br><span class="line">        <span class="type">JedisPoolConfig</span> <span class="variable">jedisPoolConfig</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JedisPoolConfig</span>();</span><br><span class="line">        jedisPoolConfig.setMaxTotal(maxTotal);</span><br><span class="line">        jedisPoolConfig.setMaxIdle(maxIdle);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//初始化Jedis连接池</span></span><br><span class="line">        jedisPool = <span class="keyword">new</span> <span class="title class_">JedisPool</span>(jedisPoolConfig, host, port);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取Jedis连接</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> Jedis <span class="title function_">getJedis</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> jedisPool.getResource();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="五、Jedis-的-Scala-工具类"><a href="#五、Jedis-的-Scala-工具类" class="headerlink" title="五、Jedis 的 Scala 工具类"></a>五、Jedis 的 Scala 工具类</h2><p>封装连接参数：src&#x2F;config.properties</p>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jedis.host</span>=<span class="string">192.168.8.100</span></span><br><span class="line"><span class="attr">jedis.port</span>=<span class="string">6379</span></span><br></pre></td></tr></table></figure>

<p>工具类代码：RedisUtils.scala</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> redis.jedis.test.utils</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.&#123;<span class="type">Jedis</span>, <span class="type">JedisPool</span>, <span class="type">JedisPoolConfig</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">object</span> <span class="title">RedisUtil</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> jedisPool:<span class="type">JedisPool</span>=<span class="literal">null</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getJedisClient</span></span>: <span class="type">Jedis</span> = &#123;</span><br><span class="line">        <span class="keyword">if</span>(jedisPool==<span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="keyword">val</span> config = <span class="type">PropertiesUtil</span>.load(<span class="string">&quot;config.properties&quot;</span>)</span><br><span class="line">            <span class="keyword">val</span> host = config.getProperty(<span class="string">&quot;redis.host&quot;</span>)</span><br><span class="line">            <span class="keyword">val</span> port = config.getProperty(<span class="string">&quot;redis.port&quot;</span>)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">val</span> jedisPoolConfig = <span class="keyword">new</span> <span class="type">JedisPoolConfig</span>()</span><br><span class="line">            jedisPoolConfig.setMaxTotal(<span class="number">100</span>) <span class="comment">//最大连接数</span></span><br><span class="line">            jedisPoolConfig.setMaxIdle(<span class="number">20</span>) <span class="comment">//最大空闲</span></span><br><span class="line">            jedisPoolConfig.setMinIdle(<span class="number">20</span>) <span class="comment">//最小空闲</span></span><br><span class="line">            jedisPoolConfig.setBlockWhenExhausted(<span class="literal">true</span>) <span class="comment">//忙碌时是否等待</span></span><br><span class="line">            jedisPoolConfig.setMaxWaitMillis(<span class="number">500</span>) <span class="comment">//忙碌时等待时长 毫秒</span></span><br><span class="line">            jedisPoolConfig.setTestOnBorrow(<span class="literal">true</span>) <span class="comment">//每次获得连接的进行测试</span></span><br><span class="line"></span><br><span class="line">            jedisPool=<span class="keyword">new</span> <span class="type">JedisPool</span>(jedisPoolConfig,host,port.toInt)</span><br><span class="line">        &#125;</span><br><span class="line">        jedisPool.getResource</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="Redis事务"><a href="#Redis事务" class="headerlink" title="Redis事务"></a>Redis事务</h1><p>Redis 事务是一个单独的隔离操作：事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中，不会被其他客户端发送来的命令请求所打断。 </p>
<p>Redis 事务的主要作用就是串联多个命令防止别的命令插队。</p>
<h2 id="一、Multi、Exec、discard"><a href="#一、Multi、Exec、discard" class="headerlink" title="一、Multi、Exec、discard"></a>一、Multi、Exec、discard</h2><p>从输入 Multi 命令开始，输入的命令都会依次进入命令队列中，但不会执行，直到输入Exec 后，Redis 会将之前的命令队列中的命令依次执行。</p>
<h2 id="二、Redis-事务的错误处理"><a href="#二、Redis-事务的错误处理" class="headerlink" title="二、Redis 事务的错误处理"></a>二、Redis 事务的错误处理</h2><ol>
<li><strong>组队过程中，可以通过 discard 命令来放弃组队</strong></li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/12_Redis%E4%BA%8B%E5%8A%A1_discard1.png" alt="discard"></p>
<p><strong>示例</strong></p>
<p><img src="/oct25-xxxxx/img/redis/13_Redis%E4%BA%8B%E5%8A%A1_discard2.png" alt="命令操作"></p>
<ol start="2">
<li><strong>组队中，某个命令出现了错误，输入执行命令时，整个命令队列都会被取消</strong></li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/15_Redis%E4%BA%8B%E5%8A%A1_%E7%BB%84%E9%98%9F%E6%8A%A5%E9%94%991.png" alt="组队出错"></p>
<p><strong>示例</strong></p>
<p><img src="/oct25-xxxxx/img/redis/16_Redis%E4%BA%8B%E5%8A%A1_%E7%BB%84%E9%98%9F%E6%8A%A5%E9%94%992.png" alt="命令操作"></p>
<ol start="3">
<li><strong>如果执行阶段某个命令报错，则只有该报错的命令不会被执行，其他的命令不会回滚，继续执行</strong></li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/17_Redis%E4%BA%8B%E5%8A%A1_%E6%89%A7%E8%A1%8C%E6%8A%A5%E9%94%991.png" alt="执行出错"></p>
<p><strong>示例</strong></p>
<p><img src="/oct25-xxxxx/img/redis/18_Redis%E4%BA%8B%E5%8A%A1_%E6%89%A7%E8%A1%8C%E6%8A%A5%E9%94%992.png" alt="命令操作"></p>
<h2 id="三、Redis-事务的锁机制"><a href="#三、Redis-事务的锁机制" class="headerlink" title="三、Redis 事务的锁机制"></a>三、Redis 事务的锁机制</h2><p>悲观锁：每次在拿数据的时候都会上锁，这样别人想拿这个数据就会block直到它拿到锁。 </p>
<p>乐观锁：每次去拿数据的时候都认为别人不会修改，所以不会上锁，但是在更新的时候会判断一下在此期间别人有没有去更新这个数据，可以使用版本号等机制。</p>
<p><img src="/oct25-xxxxx/img/redis/19_Redis%E9%94%81%E6%9C%BA%E5%88%B6.png" alt="悲观锁和乐观锁"></p>
<p>Redis 事务乐观锁——上锁与解锁</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">watch key [key ...]		# 为某个或多个 key 上锁</span><br><span class="line">unwatch					      # 取消 watch 命令对所有 key 的监视</span><br></pre></td></tr></table></figure>

<h2 id="四、Redis-事务的三特性"><a href="#四、Redis-事务的三特性" class="headerlink" title="四、Redis 事务的三特性"></a>四、Redis 事务的三特性</h2><h3 id="单独的隔离操作"><a href="#单独的隔离操作" class="headerlink" title="单独的隔离操作"></a>单独的隔离操作</h3><p>事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中，不会被其他客户端发送来的命令请求所打断。</p>
<h3 id="没有隔离级别的概念"><a href="#没有隔离级别的概念" class="headerlink" title="没有隔离级别的概念"></a>没有隔离级别的概念</h3><p>队列中的命令没有提交之前都不会实际的被执行，因为事务提交前任何指令都不会被实际执行，也就不存在“事务内的查询要看到事务里的更新，在事务外查询不能看到”这个让人万分头痛的问题 。</p>
<ul>
<li>扩充：隔离级别：</li>
</ul>
<table>
<thead>
<tr>
<th>隔离级别</th>
<th>存在问题</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>读未提交</td>
<td>脏读、不可重复读、幻读</td>
<td></td>
</tr>
<tr>
<td>读已提交</td>
<td>不可重复读、幻读</td>
<td></td>
</tr>
<tr>
<td>可重复读</td>
<td>幻读</td>
<td>锁行，MySQL默认</td>
</tr>
<tr>
<td>串行化</td>
<td>无</td>
<td>锁表，Oracle默认</td>
</tr>
</tbody></table>
<ul>
<li>MySQL：四种都支持</li>
<li>Oracle：支持读已提交和串行化</li>
</ul>
<h3 id="不保证原子性"><a href="#不保证原子性" class="headerlink" title="不保证原子性"></a>不保证原子性</h3><p>Redis同一个事务中如果有一条命令执行失败，其后的命令仍然会被执行，没有回滚 。</p>
<h1 id="Redis持久化"><a href="#Redis持久化" class="headerlink" title="Redis持久化"></a>Redis持久化</h1><h2 id="一、RDB"><a href="#一、RDB" class="headerlink" title="一、RDB"></a>一、RDB</h2><p>在指定的时间间隔内将内存中的数据集快照写入磁盘，也就是行话讲的 Snapshot 快照，它恢复时是将快照文件直接读到内存里。问题：在时间间隔内备份，可能会导致数据丢失。</p>
<h3 id="备份是如何执行的"><a href="#备份是如何执行的" class="headerlink" title="备份是如何执行的"></a>备份是如何执行的</h3><p>Redis 会单独创建（fork）一个子进程来进行持久化，会先将数据写入到一个临时文件中，待持久化过程都结束了，再用这个临时文件替换上次持久化好的文件。整个过程中，主进程是不进行任何 IO 操作的，这就确保了极高的性能如果需要进行大规模数据的恢复，且对于数据恢复的完整性不是非常敏感，那 RDB 方式要比 AOF 方式更加的高效。RDB 的缺点是最后一次持久化后的数据可能丢失。</p>
<h3 id="关于-Fork"><a href="#关于-Fork" class="headerlink" title="关于 Fork"></a>关于 Fork</h3><p>在 Linux 程序中，fork() 会产生一个和父进程完全相同的子进程，但子进程在此后多会 exec 系统调用，出于效率考虑，Linux 中引入了“写时复制技术”，一般情况父进程和子进程会共用同一段物理内存，只有进程空间的各段的内容要发生变化时，才会将父进程的内容复制一份给子进程。</p>
<h3 id="RDB-的保存文件"><a href="#RDB-的保存文件" class="headerlink" title="RDB 的保存文件"></a>RDB 的保存文件</h3><ul>
<li>在 redis.conf 配置文件中（237行），默认为 dump.rdb</li>
<li>RDB 文件保存路径（247行），默认为当前路径（.&#x2F;）</li>
</ul>
<h3 id="RDB-保存策略"><a href="#RDB-保存策略" class="headerlink" title="RDB 保存策略"></a>RDB 保存策略</h3><p><img src="/oct25-xxxxx/img/redis/20_RDB1.png" alt="RDB保存策略"></p>
<p><img src="/oct25-xxxxx/img/redis/21_RDB2.png" alt="示例值"></p>
<ol>
<li>15 min 后，至少1个 key 发生变化；</li>
<li>5 min 后，至少10个 key 发生变化；</li>
<li>1 min 后，至少10000个 key 发生变化；</li>
</ol>
<h3 id="手动保存快照"><a href="#手动保存快照" class="headerlink" title="手动保存快照"></a>手动保存快照</h3><ul>
<li>save：会占用主进程进行保存操作，这样会导致程序阻塞。</li>
<li>bgsave：启动一个子线程进行保存操作。</li>
</ul>
<p>注：除了在指定时间间隔内进行持久化以外，在 Redis 关闭（shutdown）时，也会进行自动保存。</p>
<h3 id="redis-conf-相关配置"><a href="#redis-conf-相关配置" class="headerlink" title="redis.conf 相关配置"></a>redis.conf 相关配置</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># 当Redis无法写入磁盘的话，直接关掉Redis的写操作</span><br><span class="line">stop-writes-on-bgsave-error yes</span><br><span class="line"></span><br><span class="line"># 进行rdb保存时，将文件压缩</span><br><span class="line">rdbcompression yes</span><br><span class="line"></span><br><span class="line"># 在存储快照后，还可以让Redis使用CRC64算法来进行数据校验，但是这样做会增加大约10%的性能消耗，如果希望获取到最大的性能提升，可以关闭此功能</span><br><span class="line">rdbchecksum yes</span><br></pre></td></tr></table></figure>

<h3 id="RDB-备份"><a href="#RDB-备份" class="headerlink" title="RDB 备份"></a>RDB 备份</h3><ol>
<li>获取 RDB 备份文件的目录</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">config get dir</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>将该目录中所有的 *.rdb 文件拷贝到其他地方即可</li>
</ol>
<h3 id="RDB-恢复"><a href="#RDB-恢复" class="headerlink" title="RDB 恢复"></a>RDB 恢复</h3><ol>
<li>关闭 Redis</li>
<li>将之前备份好的文件拷贝到工作目录下</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">config get dir</span><br><span class="line"></span><br><span class="line">注：备份文件命名应为 dump.rdb (默认)</span><br></pre></td></tr></table></figure>

<p>启动 Redis，备份数据会直接加载</p>
<h3 id="RDB-的优点"><a href="#RDB-的优点" class="headerlink" title="RDB 的优点"></a>RDB 的优点</h3><ol>
<li>节省磁盘空间</li>
<li>恢复速度快</li>
</ol>
<h3 id="RDB-的缺点"><a href="#RDB-的缺点" class="headerlink" title="RDB 的缺点"></a>RDB 的缺点</h3><ol>
<li>虽然 Redis 在 fork 时使用了写时拷贝技术，但是如果数据庞大时还是比较消耗性能。</li>
<li>备份周期在一定时间间隔做一次备份，所以如果 Redis 意外 down 掉的话，就会丢失最后一次快照后的所有修改。</li>
</ol>
<h2 id="二、AOF"><a href="#二、AOF" class="headerlink" title="二、AOF"></a>二、AOF</h2><p>以日志的形式来记录每个写操作，将 Redis 执行过的所有写指令记录下来（读操作不记录），只许追加文件但不可以改写文件，Redis 启动之初会读取该文件重新构建数据，换言之，Redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。</p>
<h3 id="AOF-开启"><a href="#AOF-开启" class="headerlink" title="AOF 开启"></a>AOF 开启</h3><ul>
<li>AOF 默认不开启，需要手动在 redis.conf 配置文件中配置</li>
<li>AOF 生成的文件名默认为 appendonly.aof</li>
<li>AOF 生成的文件保存路径默认同 RDB 路径一致</li>
</ul>
<p><img src="/oct25-xxxxx/img/redis/22_AOF1.png" alt="AOF开启"></p>
<h3 id="AOF-和-RDB-同时开启-Redis-会采用哪一保备份策略？"><a href="#AOF-和-RDB-同时开启-Redis-会采用哪一保备份策略？" class="headerlink" title="AOF 和 RDB 同时开启 Redis 会采用哪一保备份策略？"></a>AOF 和 RDB 同时开启 Redis 会采用哪一保备份策略？</h3><p>答：AOF</p>
<p>原因：AOF 比较安全，因为会记录所有写操作。</p>
<h3 id="AOF-保存策略"><a href="#AOF-保存策略" class="headerlink" title="AOF 保存策略"></a>AOF 保存策略</h3><p><img src="/oct25-xxxxx/img/redis/23_AOF2.png" alt="AOF保存策略"></p>
<ol>
<li>始终同步，每次 Redis 的写入都会立刻记入日志；</li>
<li>每秒同步，每秒记入日志一次，如果宕机，本秒数据可能丢失；</li>
<li>不主动同步，把同步时机交给操作系统；</li>
</ol>
<h3 id="AOF-备份"><a href="#AOF-备份" class="headerlink" title="AOF 备份"></a>AOF 备份</h3><p>AOF 的备份机制和性能虽然和 RDB 不同，但是备份和恢复的操作同 RDB 一样，都是拷贝备份文件，需要恢复时再拷贝到 Redis 工作目录下，启动系统即加载。</p>
<h3 id="AOF-恢复"><a href="#AOF-恢复" class="headerlink" title="AOF 恢复"></a>AOF 恢复</h3><ol>
<li>AOF 文件的保存路径，同 RDB 的路径一致。</li>
<li>如遇到AOF文件损坏，可通过</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-check-aof  --fix  appendonly.aof</span><br></pre></td></tr></table></figure>

<p>进行恢复</p>
<h3 id="AOF-重写机制——Rewrite"><a href="#AOF-重写机制——Rewrite" class="headerlink" title="AOF 重写机制——Rewrite"></a>AOF 重写机制——Rewrite</h3><p>AOF 采用文件追加方式，为避免文件会越来越大的情况出现，新增了重写机制，当 AOF 文件的大小超过所设定的阈值时，Redis 就会启动 AOF 文件的内容压缩，只保留可以恢复数据的最小指令集。可以使用命令 bgrewriteaof。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">incrby key1 1000</span><br><span class="line">incrby key1 1000</span><br><span class="line">incrby key1 1000</span><br><span class="line"></span><br><span class="line">启用 Rewrite ==&gt;</span><br><span class="line">incrby key1 3000</span><br></pre></td></tr></table></figure>

<h3 id="Redis-如何实现重写？"><a href="#Redis-如何实现重写？" class="headerlink" title="Redis 如何实现重写？"></a>Redis 如何实现重写？</h3><p>AOF 文件持续增长而过大时，会 fork 出一条新进程来将文件重写（也是先写临时文件最后再 rename），遍历新进程的内存中数据，每条记录有一条的 Set 语句。重写 aof 文件的操作，并没有读取旧的aof文件，而是将整个内存中的数据库内容用命令的方式重写了一个新的 aof 文件，这点和快照有点类似。</p>
<h3 id="何时重写？"><a href="#何时重写？" class="headerlink" title="何时重写？"></a>何时重写？</h3><p>重写虽然可以节约大量磁盘空间，减少恢复时间。但是每次重写还是有一定的负担的，因此设定 Redis 要满足一定条件才会进行重写。</p>
<p><img src="/oct25-xxxxx/img/redis/24_AOF3.png" alt="AOF重写时机"></p>
<p>系统载入时或者上次重写完毕时，Redis 会记录此时 AOF 大小，设为 base_size，如果 Redis 的 AOF 当前大小 &gt;&#x3D;  base_size + base_size * 100%（默认）且当前大小 &gt;&#x3D; 64mb（默认）的情况下，Redis 会对 AOF 进行重写。</p>
<h3 id="AOF-优点"><a href="#AOF-优点" class="headerlink" title="AOF 优点"></a>AOF 优点</h3><ol>
<li>备份机制更稳健，丢失数据概率更低。</li>
<li>可读的日志文本，通过操作 AOF 文件，可以处理误操作。</li>
</ol>
<h3 id="AOF-缺点"><a href="#AOF-缺点" class="headerlink" title="AOF 缺点"></a>AOF 缺点</h3><ol>
<li>比起 RDB 占用更多的磁盘空间。</li>
<li>恢复备份速度要慢。</li>
<li>每次读写都同步的话，有一定的性能压力。</li>
</ol>
<h2 id="三、RDB和AOF使用哪个好？"><a href="#三、RDB和AOF使用哪个好？" class="headerlink" title="三、RDB和AOF使用哪个好？"></a>三、RDB和AOF使用哪个好？</h2><p>官方推荐两个都启用。</p>
<p>如果对数据不敏感，可以选单独用RDB。</p>
<p>不建议单独用 AOF，因为可能会出现Bug。</p>
<p>如果只是做纯内存缓存，可以都不用。</p>
<h1 id="Redis主从复制"><a href="#Redis主从复制" class="headerlink" title="Redis主从复制"></a>Redis主从复制</h1><h2 id="一、配从不配主"><a href="#一、配从不配主" class="headerlink" title="一、配从不配主"></a>一、配从不配主</h2><ol>
<li>创建文件，并在文件中包含 reidis.conf 文件</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">文件名分别为：</span><br><span class="line">    redis6379.conf</span><br><span class="line">    redis6380.conf</span><br><span class="line">    redis6381.conf</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>在三个文件中，包含 redis.conf 配置文件</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">include /root/myRedis/redis.conf</span><br></pre></td></tr></table></figure>

<ol start="3">
<li>在创建的三个配置文件中，添加相关配置</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">daemonize yes                       # 后台启动</span><br><span class="line">pidfile /var/run/redis_6379.pid     # pid文件，分别改为79，80，81</span><br><span class="line">port 6379                           # 端口号，分别改为79，80，81</span><br><span class="line">dbfilename dump6379.rdb             # 生成的 RDB 文件</span><br><span class="line">appendonly no                       # AOF 关闭</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>分别使用三个配置文件启动 redis，并使用客户端进行连接</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">redis-server redis6379.conf</span><br><span class="line">redis-cli</span><br><span class="line"></span><br><span class="line">redis-server redis6380.conf</span><br><span class="line">redis-cli -p 6381</span><br><span class="line"></span><br><span class="line">redis-server redis6381.conf</span><br><span class="line">redis-cli -p 6381</span><br></pre></td></tr></table></figure>

<ol start="5">
<li>相关命令</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">info replication        # 打印主从复制的相关信息</span><br><span class="line">slaveof &lt;ip&gt; &lt;port&gt;     # 成为某个实例的从服务器</span><br></pre></td></tr></table></figure>

<h2 id="二、一主二仆模式演示"><a href="#二、一主二仆模式演示" class="headerlink" title="二、一主二仆模式演示"></a>二、一主二仆模式演示</h2><ol>
<li>切入点问题？slave1、slave2 是从头开始复制还是从切入点开始复制？比如从 k4 进来，那之前的123是否也可以复制 ？ 从头开始复制</li>
<li>从机是否可以写？set 可否？不可以</li>
<li>主机 shutdown 后情况如何？从机是上位还是原地待命？ 原地待命</li>
<li>主机又回来了后，主机新增记录，从机还能否顺利复制？可以顺利复制</li>
<li>其中一台从机 down 后情况如何？依照原有它能跟上大部队吗？不可以</li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/25_%E4%B8%80%E4%B8%BB%E4%BA%8C%E4%BB%86.png" alt="一主二仆模式图示"></p>
<h2 id="三、主从复制原理"><a href="#三、主从复制原理" class="headerlink" title="三、主从复制原理"></a>三、主从复制原理</h2><ol>
<li>每次从机联通后，都会给主机发送 sync 指令</li>
<li>主机立刻进行存盘操作，发送RDB文件，给从机</li>
<li>从机收到RDB文件后，进行全盘加载</li>
<li>之后每次主机的写操作，都会立刻发送给从机，从机执行相同的命令</li>
</ol>
<h2 id="四、薪火相传模式"><a href="#四、薪火相传模式" class="headerlink" title="四、薪火相传模式"></a>四、薪火相传模式</h2><ol>
<li>上一个 slave 可以是下一个 slave 的 Master，slave 同样可以接收其他 slaves 的连接和同步请求，那么该 slave 作为了链条中下一个的 master，可以有效减轻 master 的写压力，去中心化降低风险。</li>
<li>用以下命令成为某主机的从机：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">slaveof &lt;ip&gt; &lt;port&gt;</span><br></pre></td></tr></table></figure>

<ol>
<li>中途变更转向:会清除之前的数据，重新建立拷贝最新的。</li>
<li>风险是一旦某个slave 宕机，后面的 slave 都没法备份。</li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/26_%E8%96%AA%E7%81%AB%E7%9B%B8%E4%BC%A0.png" alt="薪火相传模式"></p>
<h2 id="五、反客为主"><a href="#五、反客为主" class="headerlink" title="五、反客为主"></a>五、反客为主</h2><ol>
<li>当一个master宕机后，后面的slave可以立刻升为master，其后面的slave不用做任何修改。</li>
<li>用以下命令，将从机变为主机。</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">slaveof  no one</span><br></pre></td></tr></table></figure>

<p>注：在从机反客为主后，原主机的从机不会跟随！！！其依旧是原主机的从机！！！</p>
<h2 id="六、哨兵模式"><a href="#六、哨兵模式" class="headerlink" title="六、哨兵模式"></a>六、哨兵模式</h2><p>反客为主的自动版，能够后台监控主机是否故障，如果故障了根据投票数自动将从库转换为主库。</p>
<p><img src="/oct25-xxxxx/img/redis/27_%E5%93%A8%E5%85%B5%E6%A8%A1%E5%BC%8F.png" alt="哨兵模式"></p>
<h3 id="配置哨兵"><a href="#配置哨兵" class="headerlink" title="配置哨兵"></a>配置哨兵</h3><ol>
<li>调整为一主二仆模式；</li>
<li>在自定义的 &#x2F;myRedis 目录下新建 sentinel.conf 文件；</li>
<li>在 sentinel.conf 文件中添加如下配置：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sentinel  monitor  mymaster  127.0.0.1  6379  1</span><br></pre></td></tr></table></figure>

<ul>
<li>mymaster：是为监控对象起的服务器名称；</li>
<li>1：为至少有多少个哨兵同意迁移的数量；</li>
</ul>
<h3 id="哨兵的启动"><a href="#哨兵的启动" class="headerlink" title="哨兵的启动"></a>哨兵的启动</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-sentinel /root/myRedis/sentinel.conf</span><br></pre></td></tr></table></figure>

<h3 id="故障恢复"><a href="#故障恢复" class="headerlink" title="故障恢复"></a>故障恢复</h3><ol>
<li>新主登基<ul>
<li>从下线的主服务的所有从服务里面挑选一个从服务，将其转成主服务 选择条件依次为：<ul>
<li>选择优先级靠前的；</li>
<li>选择偏移量最大的；</li>
<li>选择 runid 最小的从服务；</li>
</ul>
</li>
</ul>
</li>
<li>群仆俯首<ul>
<li>挑选出新的主服务之后，sentinel 向原主服务的从服务发送 slaveof 新主服务的命令，复制新master</li>
</ul>
</li>
<li>旧主俯首<ul>
<li>当已下线的服务重新上线时，sentinel 会向其发送 slaveof 命令，让其成为新主的从Redis 集群</li>
</ul>
</li>
</ol>
<ul>
<li>优先级在 redis.conf 中 slave-priority 100</li>
<li>偏移量是指获得原主数据最多的</li>
<li>每个 redis 实例启动后都会随机生成一个40位的 runid</li>
</ul>
<h1 id="Redis集群"><a href="#Redis集群" class="headerlink" title="Redis集群"></a>Redis集群</h1><h2 id="一、问题"><a href="#一、问题" class="headerlink" title="一、问题"></a>一、问题</h2><ul>
<li>容量不够，redis如何进行扩容？</li>
<li>并发写操作， redis如何分摊？</li>
</ul>
<h2 id="二、什么是集群"><a href="#二、什么是集群" class="headerlink" title="二、什么是集群"></a>二、什么是集群</h2><p>Redis 集群实现了对 Redis 的水平扩容，即启动 N 个 redis节点，将整个数据库分布存储在这 N 个节点中，每个节点存储总数据的1&#x2F;N。</p>
<p>Redis 集群通过分区（partition）来提供一定程度的可用性（availability）： 即使集群中有一部分节点失效或者无法进行通讯， 集群也可以继续处理命令请求。</p>
<h2 id="三、安装-ruby-环境"><a href="#三、安装-ruby-环境" class="headerlink" title="三、安装 ruby 环境"></a>三、安装 ruby 环境</h2><ol>
<li>执行如下命令安装：</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yum install ruby</span><br><span class="line">yum install rubygems</span><br></pre></td></tr></table></figure>

<ol start="2">
<li><p>拷贝redis-3.2.0.gem到&#x2F;opt目录下</p>
</li>
<li><p>执行在opt目录下执行如下命令：</p>
</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gem install --local redis-3.2.0.gem</span><br></pre></td></tr></table></figure>

<h2 id="四、Redis-Cluster-配置修改"><a href="#四、Redis-Cluster-配置修改" class="headerlink" title="四、Redis Cluster 配置修改"></a>四、Redis Cluster 配置修改</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cluster-enabled yes                     # 打开集群模式</span><br><span class="line">cluster-config-file nodes-6379.conf     # 设定节点配置文件名</span><br><span class="line">cluster-node-timeout 15000              # 设定节点失联时间，超过该时间（毫秒），集群自动进行主从切换。</span><br></pre></td></tr></table></figure>

<h2 id="五、创建6个实例"><a href="#五、创建6个实例" class="headerlink" title="五、创建6个实例"></a>五、创建6个实例</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">6379,6380,6381 =》 master</span><br><span class="line">6389,6390,6391 =》 slave</span><br></pre></td></tr></table></figure>

<p>补充：快速替换命令：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:%s/6379/6380</span><br></pre></td></tr></table></figure>

<h2 id="六、启动六个实例"><a href="#六、启动六个实例" class="headerlink" title="六、启动六个实例"></a>六、启动六个实例</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">redis-server redis6379.conf</span><br><span class="line">剩余节点启动省略...</span><br><span class="line"></span><br><span class="line">启动后确保生成的 node-*.conf 文件都正常生成</span><br></pre></td></tr></table></figure>

<h2 id="七、将六个节点合成一个集群"><a href="#七、将六个节点合成一个集群" class="headerlink" title="七、将六个节点合成一个集群"></a>七、将六个节点合成一个集群</h2><ol>
<li>进入到 Redis 下的 src 目录中</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd  /opt/redis-3.2.5/src</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>输入以下命令进行合成集群</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">./redis-trib.rb create --replicas 1 192.168.8.100:6379 192.168.8.100:6380 192.168.8.100:6381 192.168.8.100:6389 192.168.8.100:6390 192.168.8.100:6391</span><br><span class="line"></span><br><span class="line">进入集群后可以通过</span><br><span class="line">cluster nodes</span><br><span class="line">查询集群信息</span><br></pre></td></tr></table></figure>

<p>注：</p>
<ul>
<li>该命令中的 1 为每个 master 有多少个从机；</li>
<li>六个节点的前三个为 master，后三个为 slaver；</li>
</ul>
<p><img src="/oct25-xxxxx/img/redis/28_%E6%8F%92%E6%A7%BD.png" alt="插槽"></p>
<h2 id="八、Slots-插槽"><a href="#八、Slots-插槽" class="headerlink" title="八、Slots 插槽"></a>八、<strong>Slots 插槽</strong></h2><blockquote>
<p>一个 Redis 集群包含 16384 个插槽（hash slot），数据库中的每个键都属于这 16384 个插槽的其中一个， 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽， 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。</p>
</blockquote>
<h2 id="九、在集群中录入值"><a href="#九、在集群中录入值" class="headerlink" title="九、在集群中录入值"></a>九、<strong>在集群中录入值</strong></h2><h3 id="9-1-连接集群"><a href="#9-1-连接集群" class="headerlink" title="9.1 连接集群"></a>9.1 连接集群</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">redis-cli -c -p 6379</span><br><span class="line"></span><br><span class="line">通过 -c 参数实现自动重定向</span><br><span class="line">[root@hadoop100 ~]# redis-cli -c -p 6379</span><br><span class="line">127.0.0.1:6379&gt; set key1 value1</span><br><span class="line">-&gt; Redirected to slot [9189] located at 192.168.8.100:6380</span><br><span class="line">OK</span><br><span class="line">192.168.8.100:6380&gt; set key2 value2</span><br><span class="line">-&gt; Redirected to slot [4998] located at 192.168.8.100:6379</span><br><span class="line">OK</span><br><span class="line">192.168.8.100:6380&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">注：</span><br><span class="line">不在一个 slot 下键值，是不的能使用 mget，mset 等多键操作。</span><br><span class="line">可以通过&#123;&#125;来定义组的概念，从而使key中&#123;&#125;内相同内容的键值对放到一个slot中去。</span><br></pre></td></tr></table></figure>

<h2 id="十、查询群集中的值"><a href="#十、查询群集中的值" class="headerlink" title="十、查询群集中的值"></a>十、<strong>查询群集中的值</strong></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">CLUSTER KEYSLOT &lt;key&gt;                   计算键 key 应该被放置在哪个槽上。</span><br><span class="line">CLUSTER COUNTKEYSINSLOT &lt;slot&gt;          返回槽 slot 目前包含的键值对数量。</span><br><span class="line">CLUSTER GETKEYSINSLOT &lt;slot&gt; &lt;count&gt;    返回 count 个 slot 槽中的键。</span><br></pre></td></tr></table></figure>

<h2 id="十一、故障恢复"><a href="#十一、故障恢复" class="headerlink" title="十一、故障恢复"></a>十一、<strong>故障恢复</strong></h2><ol>
<li>如果主节点下线？从节点能否自动升为主节点？    可以</li>
<li>主节点恢复后，主从关系会如何？    角色互换</li>
<li>如果所有某一段插槽的主从节点都宕掉，redis服务是否还能继续?<ul>
<li>如果 cluster-require-full-coverage&#x3D;yes，则集群下线；</li>
<li>如果 cluster-require-full-coverage&#x3D;no，则可以继续使用，不过会丢失数据</li>
</ul>
</li>
</ol>
<p><img src="/oct25-xxxxx/img/redis/29_%E6%95%85%E9%9A%9C%E6%81%A2%E5%A4%8D.png"></p>
<h2 id="十二、Redis-集群优点"><a href="#十二、Redis-集群优点" class="headerlink" title="十二、Redis 集群优点"></a>十二、<strong>Redis 集群优点</strong></h2><ol>
<li>实现扩容；</li>
<li>分摊压力；</li>
<li>无中心配置相对简单；</li>
</ol>
<h2 id="十三、Redis-集群不足"><a href="#十三、Redis-集群不足" class="headerlink" title="十三、Redis 集群不足"></a>十三、<strong>Redis 集群不足</strong></h2><ol>
<li>多键操作是不被支持的；</li>
<li>多键的 Redis 事务是不被支持的。lua 脚本不被支持；</li>
<li>由于集群方案出现较晚，很多公司已经采用了其他的集群方案，而代理或者客户端分片的方案想要迁移至redis cluster，需要整体迁移而不是逐步过渡，复杂度较大；</li>
</ol>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Oct25-X</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://oct25-x.atomgit.net/oct25-xxxxx/2023/07/04/10%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%BC%80%E6%BA%90%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93%20Redis/">https://oct25-x.atomgit.net/oct25-xxxxx/2023/07/04/10%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%BC%80%E6%BA%90%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93%20Redis/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://oct25-x.atomgit.net/oct25-xxxxx" target="_blank">Oct25-X</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/oct25-xxxxx/tags/Redis/">Redis</a></div><div class="post_share"><div class="social-share" data-image="/oct25-xxxxx/img/cover_img/ctt10.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/oct25-xxxxx/2023/07/08/12Redis-%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF%EF%BC%8C%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F%EF%BC%8C%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9/"><img class="prev-cover" src="/oct25-xxxxx/img/cover_img/ctt12.png" onerror="onerror=null;src='/oct25-xxxxx/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Redis 缓存击穿，缓存穿透，缓存雪崩</div></div></a></div><div class="next-post pull-right"><a href="/oct25-xxxxx/2023/06/30/09%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%88%86%E5%B8%83%E5%BC%8F%E5%8D%8F%E8%B0%83%E7%B3%BB%E7%BB%9F%20Zookeeper/"><img class="next-cover" src="/oct25-xxxxx/img/cover_img/ctt9.png" onerror="onerror=null;src='/oct25-xxxxx/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">大数据之分布式协调系统 Zookeeper</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/oct25-xxxxx/2023/07/08/11Redis%20%E4%B8%8E%20MySQL%20%E7%9A%84%E6%95%B0%E6%8D%AE%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/" title="Redis 与 MySQL 的数据一致性问题"><img class="cover" src="/oct25-xxxxx/img/cover_img/ctt11.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-07-08</div><div class="title">Redis 与 MySQL 的数据一致性问题</div></div></a></div><div><a href="/oct25-xxxxx/2023/07/08/12Redis-%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF%EF%BC%8C%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F%EF%BC%8C%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9/" title="Redis 缓存击穿，缓存穿透，缓存雪崩"><img class="cover" src="/oct25-xxxxx/img/cover_img/ctt12.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-07-08</div><div class="title">Redis 缓存击穿，缓存穿透，缓存雪崩</div></div></a></div><div><a href="/oct25-xxxxx/2023/09/02/28Redis-%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF/" title="Redis 设置开机自启"><img class="cover" src="/oct25-xxxxx/img/cover_img/ctt28.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-09-02</div><div class="title">Redis 设置开机自启</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/oct25-xxxxx/img/avatar.jpg" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">Oct25-X</div><div class="author-info__description"></div></div><div class="card-info-data is-center"><div class="card-info-data-item"><a href="/oct25-xxxxx/archives/"><div class="headline">文章</div><div class="length-num">52</div></a></div><div class="card-info-data-item"><a href="/oct25-xxxxx/tags/"><div class="headline">标签</div><div class="length-num">17</div></a></div><div class="card-info-data-item"><a href="/oct25-xxxxx/categories/"><div class="headline">分类</div><div class="length-num">8</div></a></div></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/xxxxxx"><i class="fab fa-github"></i><span>Follow Me</span></a></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%80%E4%BB%8B"><span class="toc-number">1.</span> <span class="toc-text">数据库简介</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81NoSQL-%E6%A6%82%E8%BF%B0"><span class="toc-number">1.1.</span> <span class="toc-text">一、NoSQL 概述</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81NoSQL-%E7%9A%84%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">1.2.</span> <span class="toc-text">二、NoSQL 的适用场景</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81NoSQL-%E4%B8%8D%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">1.3.</span> <span class="toc-text">三、NoSQL 不适用场景</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81NoSQL-%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">1.4.</span> <span class="toc-text">四、NoSQL 数据库</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">1.4.1.</span> <span class="toc-text">缓存数据库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%87%E6%A1%A3%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">1.4.2.</span> <span class="toc-text">文档数据库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%97%E5%BC%8F%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">1.4.3.</span> <span class="toc-text">列式数据库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%BE%E5%85%B3%E7%B3%BB%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">1.4.4.</span> <span class="toc-text">图关系数据库</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis-%E4%BB%8B%E7%BB%8D%E5%8F%8A%E5%AE%89%E8%A3%85%E5%90%AF%E5%8A%A8"><span class="toc-number">2.</span> <span class="toc-text">Redis 介绍及安装启动</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81Redis%E4%BB%8B%E7%BB%8D"><span class="toc-number">2.1.</span> <span class="toc-text">一、Redis介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81Redis-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-number">2.2.</span> <span class="toc-text">二、Redis 应用场景</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81Redis-%E5%AE%89%E8%A3%85"><span class="toc-number">2.3.</span> <span class="toc-text">三、Redis 安装</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85%E9%83%A8%E7%BD%B2-Redis"><span class="toc-number">2.3.1.</span> <span class="toc-text">安装部署 Redis</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE-Redis-%E5%90%8E%E5%8F%B0%E5%90%AF%E5%8A%A8"><span class="toc-number">2.3.2.</span> <span class="toc-text">配置 Redis 后台启动</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE-Redis-%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5"><span class="toc-number">2.3.3.</span> <span class="toc-text">配置 Redis 远程连接</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Redis-%E5%85%B3%E9%97%AD"><span class="toc-number">2.3.4.</span> <span class="toc-text">Redis 关闭</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81Redis-%E7%9A%84%E5%8D%95%E7%BA%BF%E7%A8%8B-%E5%A4%9A%E8%B7%AF-IO-%E5%A4%8D%E7%94%A8%E6%8A%80%E6%9C%AF"><span class="toc-number">2.4.</span> <span class="toc-text">四、Redis 的单线程 + 多路 IO 复用技术</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis-%E4%BA%94%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="toc-number">3.</span> <span class="toc-text">Redis 五大数据类型</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81Key"><span class="toc-number">3.1.</span> <span class="toc-text">一、Key</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81String"><span class="toc-number">3.2.</span> <span class="toc-text">二、String</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E5%AD%90%E6%80%A7"><span class="toc-number">3.2.1.</span> <span class="toc-text">原子性</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81List"><span class="toc-number">3.3.</span> <span class="toc-text">三、List</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81Set"><span class="toc-number">3.4.</span> <span class="toc-text">四、Set</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81Hash"><span class="toc-number">3.5.</span> <span class="toc-text">五、Hash</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Hash-%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8"><span class="toc-number">3.5.1.</span> <span class="toc-text">Hash 数据的存储</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81Zset"><span class="toc-number">3.6.</span> <span class="toc-text">六、Zset</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis-%E7%9A%84-Java-%E5%AE%A2%E6%88%B7%E7%AB%AF-Jedis"><span class="toc-number">4.</span> <span class="toc-text">Redis 的 Java 客户端 Jedis</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81Jedis-%E7%AE%80%E4%BB%8B"><span class="toc-number">4.1.</span> <span class="toc-text">一、Jedis 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81Jedis-%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">4.2.</span> <span class="toc-text">二、Jedis 的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81Jedis-%E8%BF%9E%E6%8E%A5%E6%B1%A0"><span class="toc-number">4.3.</span> <span class="toc-text">三、Jedis 连接池</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89-Jedis-%E8%BF%9E%E6%8E%A5%E6%B1%A0%E7%9A%84%E5%8F%82%E6%95%B0"><span class="toc-number">4.3.1.</span> <span class="toc-text">自定义 Jedis 连接池的参数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81Jedis-%E7%9A%84-Java-%E5%B7%A5%E5%85%B7%E7%B1%BB"><span class="toc-number">4.4.</span> <span class="toc-text">四、Jedis 的 Java 工具类</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81Jedis-%E7%9A%84-Scala-%E5%B7%A5%E5%85%B7%E7%B1%BB"><span class="toc-number">4.5.</span> <span class="toc-text">五、Jedis 的 Scala 工具类</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis%E4%BA%8B%E5%8A%A1"><span class="toc-number">5.</span> <span class="toc-text">Redis事务</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81Multi%E3%80%81Exec%E3%80%81discard"><span class="toc-number">5.1.</span> <span class="toc-text">一、Multi、Exec、discard</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81Redis-%E4%BA%8B%E5%8A%A1%E7%9A%84%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86"><span class="toc-number">5.2.</span> <span class="toc-text">二、Redis 事务的错误处理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81Redis-%E4%BA%8B%E5%8A%A1%E7%9A%84%E9%94%81%E6%9C%BA%E5%88%B6"><span class="toc-number">5.3.</span> <span class="toc-text">三、Redis 事务的锁机制</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81Redis-%E4%BA%8B%E5%8A%A1%E7%9A%84%E4%B8%89%E7%89%B9%E6%80%A7"><span class="toc-number">5.4.</span> <span class="toc-text">四、Redis 事务的三特性</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8D%95%E7%8B%AC%E7%9A%84%E9%9A%94%E7%A6%BB%E6%93%8D%E4%BD%9C"><span class="toc-number">5.4.1.</span> <span class="toc-text">单独的隔离操作</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B2%A1%E6%9C%89%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB%E7%9A%84%E6%A6%82%E5%BF%B5"><span class="toc-number">5.4.2.</span> <span class="toc-text">没有隔离级别的概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%8D%E4%BF%9D%E8%AF%81%E5%8E%9F%E5%AD%90%E6%80%A7"><span class="toc-number">5.4.3.</span> <span class="toc-text">不保证原子性</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis%E6%8C%81%E4%B9%85%E5%8C%96"><span class="toc-number">6.</span> <span class="toc-text">Redis持久化</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81RDB"><span class="toc-number">6.1.</span> <span class="toc-text">一、RDB</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%87%E4%BB%BD%E6%98%AF%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E7%9A%84"><span class="toc-number">6.1.1.</span> <span class="toc-text">备份是如何执行的</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E-Fork"><span class="toc-number">6.1.2.</span> <span class="toc-text">关于 Fork</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E7%9A%84%E4%BF%9D%E5%AD%98%E6%96%87%E4%BB%B6"><span class="toc-number">6.1.3.</span> <span class="toc-text">RDB 的保存文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E4%BF%9D%E5%AD%98%E7%AD%96%E7%95%A5"><span class="toc-number">6.1.4.</span> <span class="toc-text">RDB 保存策略</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%8B%E5%8A%A8%E4%BF%9D%E5%AD%98%E5%BF%AB%E7%85%A7"><span class="toc-number">6.1.5.</span> <span class="toc-text">手动保存快照</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#redis-conf-%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE"><span class="toc-number">6.1.6.</span> <span class="toc-text">redis.conf 相关配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E5%A4%87%E4%BB%BD"><span class="toc-number">6.1.7.</span> <span class="toc-text">RDB 备份</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E6%81%A2%E5%A4%8D"><span class="toc-number">6.1.8.</span> <span class="toc-text">RDB 恢复</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E7%9A%84%E4%BC%98%E7%82%B9"><span class="toc-number">6.1.9.</span> <span class="toc-text">RDB 的优点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RDB-%E7%9A%84%E7%BC%BA%E7%82%B9"><span class="toc-number">6.1.10.</span> <span class="toc-text">RDB 的缺点</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81AOF"><span class="toc-number">6.2.</span> <span class="toc-text">二、AOF</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E5%BC%80%E5%90%AF"><span class="toc-number">6.2.1.</span> <span class="toc-text">AOF 开启</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E5%92%8C-RDB-%E5%90%8C%E6%97%B6%E5%BC%80%E5%90%AF-Redis-%E4%BC%9A%E9%87%87%E7%94%A8%E5%93%AA%E4%B8%80%E4%BF%9D%E5%A4%87%E4%BB%BD%E7%AD%96%E7%95%A5%EF%BC%9F"><span class="toc-number">6.2.2.</span> <span class="toc-text">AOF 和 RDB 同时开启 Redis 会采用哪一保备份策略？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E4%BF%9D%E5%AD%98%E7%AD%96%E7%95%A5"><span class="toc-number">6.2.3.</span> <span class="toc-text">AOF 保存策略</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E5%A4%87%E4%BB%BD"><span class="toc-number">6.2.4.</span> <span class="toc-text">AOF 备份</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E6%81%A2%E5%A4%8D"><span class="toc-number">6.2.5.</span> <span class="toc-text">AOF 恢复</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E9%87%8D%E5%86%99%E6%9C%BA%E5%88%B6%E2%80%94%E2%80%94Rewrite"><span class="toc-number">6.2.6.</span> <span class="toc-text">AOF 重写机制——Rewrite</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Redis-%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E9%87%8D%E5%86%99%EF%BC%9F"><span class="toc-number">6.2.7.</span> <span class="toc-text">Redis 如何实现重写？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%95%E6%97%B6%E9%87%8D%E5%86%99%EF%BC%9F"><span class="toc-number">6.2.8.</span> <span class="toc-text">何时重写？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E4%BC%98%E7%82%B9"><span class="toc-number">6.2.9.</span> <span class="toc-text">AOF 优点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AOF-%E7%BC%BA%E7%82%B9"><span class="toc-number">6.2.10.</span> <span class="toc-text">AOF 缺点</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81RDB%E5%92%8CAOF%E4%BD%BF%E7%94%A8%E5%93%AA%E4%B8%AA%E5%A5%BD%EF%BC%9F"><span class="toc-number">6.3.</span> <span class="toc-text">三、RDB和AOF使用哪个好？</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6"><span class="toc-number">7.</span> <span class="toc-text">Redis主从复制</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E9%85%8D%E4%BB%8E%E4%B8%8D%E9%85%8D%E4%B8%BB"><span class="toc-number">7.1.</span> <span class="toc-text">一、配从不配主</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E4%B8%80%E4%B8%BB%E4%BA%8C%E4%BB%86%E6%A8%A1%E5%BC%8F%E6%BC%94%E7%A4%BA"><span class="toc-number">7.2.</span> <span class="toc-text">二、一主二仆模式演示</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E5%8E%9F%E7%90%86"><span class="toc-number">7.3.</span> <span class="toc-text">三、主从复制原理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E8%96%AA%E7%81%AB%E7%9B%B8%E4%BC%A0%E6%A8%A1%E5%BC%8F"><span class="toc-number">7.4.</span> <span class="toc-text">四、薪火相传模式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81%E5%8F%8D%E5%AE%A2%E4%B8%BA%E4%B8%BB"><span class="toc-number">7.5.</span> <span class="toc-text">五、反客为主</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E5%93%A8%E5%85%B5%E6%A8%A1%E5%BC%8F"><span class="toc-number">7.6.</span> <span class="toc-text">六、哨兵模式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E5%93%A8%E5%85%B5"><span class="toc-number">7.6.1.</span> <span class="toc-text">配置哨兵</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%93%A8%E5%85%B5%E7%9A%84%E5%90%AF%E5%8A%A8"><span class="toc-number">7.6.2.</span> <span class="toc-text">哨兵的启动</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%85%E9%9A%9C%E6%81%A2%E5%A4%8D"><span class="toc-number">7.6.3.</span> <span class="toc-text">故障恢复</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Redis%E9%9B%86%E7%BE%A4"><span class="toc-number">8.</span> <span class="toc-text">Redis集群</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E9%97%AE%E9%A2%98"><span class="toc-number">8.1.</span> <span class="toc-text">一、问题</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E4%BB%80%E4%B9%88%E6%98%AF%E9%9B%86%E7%BE%A4"><span class="toc-number">8.2.</span> <span class="toc-text">二、什么是集群</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E5%AE%89%E8%A3%85-ruby-%E7%8E%AF%E5%A2%83"><span class="toc-number">8.3.</span> <span class="toc-text">三、安装 ruby 环境</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%9B%E3%80%81Redis-Cluster-%E9%85%8D%E7%BD%AE%E4%BF%AE%E6%94%B9"><span class="toc-number">8.4.</span> <span class="toc-text">四、Redis Cluster 配置修改</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%94%E3%80%81%E5%88%9B%E5%BB%BA6%E4%B8%AA%E5%AE%9E%E4%BE%8B"><span class="toc-number">8.5.</span> <span class="toc-text">五、创建6个实例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AD%E3%80%81%E5%90%AF%E5%8A%A8%E5%85%AD%E4%B8%AA%E5%AE%9E%E4%BE%8B"><span class="toc-number">8.6.</span> <span class="toc-text">六、启动六个实例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%83%E3%80%81%E5%B0%86%E5%85%AD%E4%B8%AA%E8%8A%82%E7%82%B9%E5%90%88%E6%88%90%E4%B8%80%E4%B8%AA%E9%9B%86%E7%BE%A4"><span class="toc-number">8.7.</span> <span class="toc-text">七、将六个节点合成一个集群</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%AB%E3%80%81Slots-%E6%8F%92%E6%A7%BD"><span class="toc-number">8.8.</span> <span class="toc-text">八、Slots 插槽</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B9%9D%E3%80%81%E5%9C%A8%E9%9B%86%E7%BE%A4%E4%B8%AD%E5%BD%95%E5%85%A5%E5%80%BC"><span class="toc-number">8.9.</span> <span class="toc-text">九、在集群中录入值</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#9-1-%E8%BF%9E%E6%8E%A5%E9%9B%86%E7%BE%A4"><span class="toc-number">8.9.1.</span> <span class="toc-text">9.1 连接集群</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%81%E3%80%81%E6%9F%A5%E8%AF%A2%E7%BE%A4%E9%9B%86%E4%B8%AD%E7%9A%84%E5%80%BC"><span class="toc-number">8.10.</span> <span class="toc-text">十、查询群集中的值</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%81%E4%B8%80%E3%80%81%E6%95%85%E9%9A%9C%E6%81%A2%E5%A4%8D"><span class="toc-number">8.11.</span> <span class="toc-text">十一、故障恢复</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%81%E4%BA%8C%E3%80%81Redis-%E9%9B%86%E7%BE%A4%E4%BC%98%E7%82%B9"><span class="toc-number">8.12.</span> <span class="toc-text">十二、Redis 集群优点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%81%E4%B8%89%E3%80%81Redis-%E9%9B%86%E7%BE%A4%E4%B8%8D%E8%B6%B3"><span class="toc-number">8.13.</span> <span class="toc-text">十三、Redis 集群不足</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/oct25-xxxxx/2024/02/24/52%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala09_%E9%9A%90%E5%BC%8F%E8%BD%AC%E6%8D%A2%E3%80%81%E5%BC%82%E5%B8%B8%E5%92%8C%E6%B3%9B%E5%9E%8B/" title="大数据之多范式编程语言 Scala09_隐式转换、异常和泛型"><img src="/oct25-xxxxx/img/cover_img/ctt52.png" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/404.jpg'" alt="大数据之多范式编程语言 Scala09_隐式转换、异常和泛型"/></a><div class="content"><a class="title" href="/oct25-xxxxx/2024/02/24/52%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala09_%E9%9A%90%E5%BC%8F%E8%BD%AC%E6%8D%A2%E3%80%81%E5%BC%82%E5%B8%B8%E5%92%8C%E6%B3%9B%E5%9E%8B/" title="大数据之多范式编程语言 Scala09_隐式转换、异常和泛型">大数据之多范式编程语言 Scala09_隐式转换、异常和泛型</a><time datetime="2024-02-24T04:55:34.000Z" title="发表于 2024-02-24 12:55:34">2024-02-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/oct25-xxxxx/2024/02/24/51%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala08_%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D/" title="大数据之多范式编程语言 Scala08_模式匹配"><img src="/oct25-xxxxx/img/cover_img/ctt51.png" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/404.jpg'" alt="大数据之多范式编程语言 Scala08_模式匹配"/></a><div class="content"><a class="title" href="/oct25-xxxxx/2024/02/24/51%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala08_%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D/" title="大数据之多范式编程语言 Scala08_模式匹配">大数据之多范式编程语言 Scala08_模式匹配</a><time datetime="2024-02-24T00:46:12.000Z" title="发表于 2024-02-24 08:46:12">2024-02-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/oct25-xxxxx/2024/02/22/50%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala07_%E9%9B%86%E5%90%88/" title="大数据之多范式编程语言 Scala07_集合"><img src="/oct25-xxxxx/img/cover_img/ctt50.png" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/404.jpg'" alt="大数据之多范式编程语言 Scala07_集合"/></a><div class="content"><a class="title" href="/oct25-xxxxx/2024/02/22/50%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala07_%E9%9B%86%E5%90%88/" title="大数据之多范式编程语言 Scala07_集合">大数据之多范式编程语言 Scala07_集合</a><time datetime="2024-02-22T08:16:10.000Z" title="发表于 2024-02-22 16:16:10">2024-02-22</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/oct25-xxxxx/2024/02/21/49%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala06_%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" title="大数据之多范式编程语言 Scala06_面向对象"><img src="/oct25-xxxxx/img/cover_img/ctt49.png" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/404.jpg'" alt="大数据之多范式编程语言 Scala06_面向对象"/></a><div class="content"><a class="title" href="/oct25-xxxxx/2024/02/21/49%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala06_%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" title="大数据之多范式编程语言 Scala06_面向对象">大数据之多范式编程语言 Scala06_面向对象</a><time datetime="2024-02-21T07:01:10.000Z" title="发表于 2024-02-21 15:01:10">2024-02-21</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/oct25-xxxxx/2024/02/20/48%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala05_%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/" title="大数据之多范式编程语言 Scala05_函数式编程"><img src="/oct25-xxxxx/img/cover_img/ctt48.png" onerror="this.onerror=null;this.src='/oct25-xxxxx/img/404.jpg'" alt="大数据之多范式编程语言 Scala05_函数式编程"/></a><div class="content"><a class="title" href="/oct25-xxxxx/2024/02/20/48%E5%A4%A7%E6%95%B0%E6%8D%AE%E4%B9%8B%E5%A4%9A%E8%8C%83%E5%BC%8F%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80Scala05_%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/" title="大数据之多范式编程语言 Scala05_函数式编程">大数据之多范式编程语言 Scala05_函数式编程</a><time datetime="2024-02-20T12:05:11.000Z" title="发表于 2024-02-20 20:05:11">2024-02-20</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('/oct25-xxxxx/img/top_img/top_bg9.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2024 By Oct25-X</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div id="rightMenu"><div class="rightMenu-group rightMenu-small"><div class="rightMenu-item" id="menu-backward"><i class="fa-solid fa-arrow-left"></i></div><div class="rightMenu-item" id="menu-forward"><i class="fa-solid fa-arrow-right"></i></div><div class="rightMenu-item" id="menu-refresh"><i class="fa-solid fa-arrow-rotate-right"></i></div><div class="rightMenu-item" id="menu-home"><i class="fa-solid fa-house"></i></div></div><div class="rightMenu-group rightMenu-line rightMenuOther"><a class="rightMenu-item menu-link" href="/archives/"><i class="fa-solid fa-archive"></i><span>文章归档</span></a><a class="rightMenu-item menu-link" href="/categories/"><i class="fa-solid fa-folder-open"></i><span>文章分类</span></a><a class="rightMenu-item menu-link" href="/tags/"><i class="fa-solid fa-tags"></i><span>文章标签</span></a></div><div class="rightMenu-group rightMenu-line rightMenuNormal"><a class="rightMenu-item" id="menu-translate"><i class="fa-solid fa-earth-asia"></i><span>繁简切换</span></a><div class="rightMenu-item" id="menu-darkmode"><i class="fa-solid fa-moon"></i><span>切换模式</span></div></div></div><div id="rightmenu-mask"></div><div><script src="/oct25-xxxxx/js/utils.js"></script><script src="/oct25-xxxxx/js/main.js"></script><script src="/oct25-xxxxx/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.js"></script><script src="/oct25-xxxxx/js/search/local-search.js"></script><div class="js-pjax"></div><script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script><script defer data-pjax src="/js/rightMenu.js"></script><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = true;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-heart.min.js" async="async" mobile="false"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>